//
// Copyright (c) 2014, 保留所有权利。
//
// CstContactSync.java
//
// 作    者：王红燕
// 当前版本：1.0
// 2014 下午6:29:41
//
// 
//
package com.vanke.agent.sync;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.log4j.Logger;

import com.vanke.agent.ADataSource;
import com.vanke.agent.common.Cache;
import com.vanke.agent.common.CstUtil;
import com.vanke.agent.common.Util;
import com.vanke.agent.common.log.LoggerUtil;

/**
 *
 */
public class CstContactSync extends AgentSync {
	private Logger log = Logger.getLogger(CstContactSync.class);
	private Logger bizLog = LoggerUtil.getLoggerByName("contact_update");
	private Logger missingLog = LoggerUtil.getLoggerByName("missing");

	@Override
	public void sync() {
		Connection con = ADataSource.getConnection(ADataSource.SCHEMA_BIZ);
		try {
			doLoadMapping(con);
			Iterator<Entry<String, Map<Long, Set<String>>>> iter;
			iter = mobileMap.entrySet().iterator();
			String day = Util.formatDate(new Date());
			bizLog.info("-----------------" + day + "-----------------");
			while (iter.hasNext()) {
				Entry<String, Map<Long, Set<String>>> entry = iter.next();
				updateTable(con, entry.getKey(), entry.getValue());
			}
			bizLog.info("--------------------------------------------");
		} catch (Exception e) {
			e.printStackTrace();
			log.error("更新客户联系方式异常：" + e);
		} finally {
			ADataSource.close(con);
			mobileMap.clear();
		}
	} //~

	/*
	 * 
	 */
	void updateTable(Connection con, String table,
			Map<Long, Set<String>> mobileMaps) {
		Map<Long, String> oldContact = contactMap.get(table);
		PreparedStatement pstmt = null;
		String sql = "update " + table + " set contact=? where cstguid=?";
		int count = 0;
		int commit = 0;
		try {
			pstmt = con.prepareStatement(sql);
			Iterator<Entry<Long, Set<String>>> iter;
			iter = mobileMaps.entrySet().iterator();
			while (iter.hasNext()) {
				count++;

				Entry<Long, Set<String>> entry = iter.next();
				Set<String> set = entry.getValue();
				long guid = entry.getKey();
				String mobiles = set.toString().replaceAll("\\[", "")
						.replaceAll("\\]", "").replaceAll(",", ";")
						.replaceAll(" ", "");
				String old = oldContact.get(guid);
				if (old == null) {
					missingLog
							.warn("[" + guid + "]is missing[" + mobiles + "]");
					continue;
				}
				if (old.equals(mobiles)) {
					continue;
				}
				bizLog.info("update[" + guid + "-" + mobiles + "]");
				set.clear();
				pstmt.setString(1, mobiles);
				pstmt.setLong(2, guid);
				pstmt.addBatch();

				if (count % 1000 == 0) {
					int[] ups = pstmt.executeBatch();
					pstmt.clearBatch();
					for (int u : ups) {
						commit += u;
					}
				}
			} // end while
			int[] ups = pstmt.executeBatch();
			pstmt.clearBatch();
			for (int u : ups) {
				commit += u;
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("[" + table + "]更新客户联系方式异常：" + e);
		} finally {
			ADataSource.close(pstmt);
			mobileMaps.clear();
		}
		log.info(table + ":" + commit + "/" + count + "已更新 ");
	} //~updateTable

	Map<String, Map<Long, Set<String>>> mobileMap = new HashMap<String, Map<Long, Set<String>>>();
	Map<String, Map<Long, String>> contactMap = new HashMap<String, Map<Long, String>>();

	/*
	 * 加载映射列表
	 */
	private int doLoadMapping(Connection con) throws SQLException {
		Statement stmt = null;
		int count = 0;

		// 加载所有映射表
		List<String> tables = Cache.loadTables(con, "cst_cstmobilemapping_");
		stmt = con.createStatement();
		for (String table : tables) { // 遍历取表
			String sql = "select mobile,CstGUID from " + table;
			ResultSet rs = stmt.executeQuery(sql);
			while (rs.next()) {
				count++;
				String mobile = rs.getString(1).trim();
				long cstguid = rs.getLong(2);

				// 计算表
				String cstPrefix = CstUtil.calcCstSplitTable("cst_Customer_",
						cstguid);

				// 按表分缓存
				Map<Long, Set<String>> cstTableMap = mobileMap.get(cstPrefix);
				if (cstTableMap == null) {
					cstTableMap = new HashMap<Long, Set<String>>();
					mobileMap.put(cstPrefix, cstTableMap);
				}
				Set<String> set = cstTableMap.get(cstguid);
				if (set == null) {
					set = new HashSet<String>();
					cstTableMap.put(cstguid, set);
				}
				set.add(mobile);
			} // end while
			log.info(table + " mapping cached");
			ADataSource.close(rs);
		} // end for (String table : tables)

		tables = Cache.loadTables(con, "cst_customer_");
		for (String table : tables) { // 遍历取表
			String sql = "select contact,CstGUID from " + table;
			ResultSet rs = stmt.executeQuery(sql);
			while (rs.next()) {
				count++;
				String contact = rs.getString(1);
				contact = contact == null ? "" : contact.trim();
				long cstguid = rs.getLong(2);
				// 计算表
				String cstPrefix = CstUtil.calcCstSplitTable("cst_Customer_",
						cstguid);
				// 按表分缓存
				Map<Long, String> cstTableMap = contactMap.get(cstPrefix);
				if (cstTableMap == null) {
					cstTableMap = new HashMap<Long, String>();
					contactMap.put(cstPrefix, cstTableMap);
				}
				cstTableMap.put(cstguid, contact);
			} // end while
			log.info(table + " mapping cached");
			ADataSource.close(rs);
		} // end for (String table : tables)

		ADataSource.close(stmt);
		Iterator<Entry<String, Map<Long, Set<String>>>> iter;
		iter = mobileMap.entrySet().iterator();
		while (iter.hasNext()) {
			Entry<String, Map<Long, Set<String>>> entry = iter.next();
			log.info(entry.getValue().size() + " cached for table "
					+ entry.getKey());
		}
		return count;
	} //~doLoadMapping
} //~
